Skip to content

feat(mining): mining page, iOS/Android builds, continuous mining#1373

Open
InspektorKek wants to merge 128 commits intomasterfrom
feat/tauri-mining
Open

feat(mining): mining page, iOS/Android builds, continuous mining#1373
InspektorKek wants to merge 128 commits intomasterfrom
feat/tauri-mining

Conversation

@InspektorKek
Copy link
Member

Summary

Full mining integration for the Cyb app — adds a mining dashboard, native iOS/Android builds, and continuous mining (no pause during proof submission).

Mining Dashboard (src/pages/Mining/)

  • Hero hashrate display with CSS pulse animation + SVG sparkline chart
  • Stat grid: LI Mined, Proofs submitted, Est. LI/hr, Elapsed time
  • LI balance (polled every 30s) + session rewards tracking
  • Proof log with TX explorer links, OK/FAIL status pills, relative timestamps
  • Thread selector (range input for CPU cores, disabled while mining)
  • Network stats: current difficulty + active miner count from on-chain query
  • WASM fallback: Web Workers with uhash-web for browser mining when not in Tauri
  • State persistence: proof log + session LI saved to localStorage; on-mount recovery detects active Rust backend mining

Tauri Native Backend (src-tauri/src/mining.rs)

  • Multi-threaded mining via uhash-core with hardware AES/SHA256 acceleration
  • Binary hash input format matching on-chain contract: seed_raw_32B || address_utf8 || timestamp_8B_LE || nonce_8B_LE
  • start_mining, stop_mining, get_mining_status, take_proofs, mining_benchmark, get_mining_params commands

Continuous Mining (key improvement)

  • Before: mining stopped when proof found → submit TX → sleep 6s → restart. ~7-10s of zero hashrate per proof.
  • After: mining never stops. Proofs queued in Vec<FoundProof>, polling loop drains queue via take_proofs, submits async (fire-and-forget).
  • Applies to both native (Rust threads) and WASM (Web Workers) paths.

iOS Build

  • Platform-specific config (tauri.ios.conf.json) — single window, no splash screen
  • #[cfg(desktop)] guards on all desktop-only code (IPFS, CozoDb, warp server, splash screen)
  • Desktop/mobile invoke handler split (mobile only registers mining commands)
  • Tested on iPhone — wallet connect + mining works end-to-end

Android Build

  • Platform-specific config (tauri.android.conf.json) — single window
  • Desktop-only deps gated in Cargo.toml: [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
    • Avoids OpenSSL cross-compilation failure (reqwest native-tls)
    • Avoids RocksDB cross-compilation (cozo)
  • BuildTask.kt fix: npx @tauri-apps/cli instead of npm run tauri
  • aarch64 onlycpufeatures crate doesn't support armv7 (32-bit ARM). All modern phones are 64-bit.
  • Tested on Galaxy A56 — APK builds and installs

Mobile UX Fixes

  • Heavy backend disabled on mobile: CozoDb, IPFS daemon, background workers, ML embeddings (33MB model), sync loops, Rune engine — all skipped via isMobileTauri check in backend.tsx
  • Safe areas: viewport-fit=cover meta tag + env(safe-area-inset-*) on header (notch), footer, action bars, modals, mobile menu
  • Wallet connection: "Connect wallet" button on Tauri mobile replaces "choose address in keplr" message; Settings + Keys routes added to mobileAllowedRoutes
  • Responsive modals: ConnectWalletModal maxWidth: calc(100vw - 32px), mnemonic grid repeat(auto-fill, minmax(100px, 1fr))

New Files

File Purpose
src/pages/Mining/Mining.tsx Main mining page component
src/pages/Mining/wasmMiner.ts WASM Web Worker manager class
src/pages/Mining/miningWorker.ts Web Worker that runs uhash-web WASM
src/pages/Mining/MiningActionBar.tsx Start/Stop mining action bar
src/pages/Mining/hooks/* useLiBalance, useRewardEstimate, useHashrateSamples, useMinerStats
src/pages/Mining/components/* HashrateHero, StatCard, ProofLogEntry, ThreadSelector
src-tauri/src/mining.rs Rust mining backend (multi-threaded, proof queue)
src-tauri/src/lib.rs Tauri entry point with desktop/mobile split
src-tauri/tauri.ios.conf.json iOS-specific single-window config
src-tauri/tauri.android.conf.json Android-specific single-window config
src/constants/mining.ts UHASH contract address constant
src/utils/tauri.ts isTauri() detection helper

Modified Files (key changes)

File Change
src-tauri/Cargo.toml Desktop-only deps gated for mobile cross-compilation
src/contexts/backend/backend.tsx Skip all heavy backend on mobile (isMobileTauri)
src/components/actionBar/index.tsx Show "Connect" button on Tauri mobile
src/containers/application/mobileAllowedRoutes.ts Added mining, settings, keys routes
src/index.html viewport-fit=cover for safe areas
Various .scss / .style.ts files Safe area insets + responsive modal sizing

Test plan

  • Desktop (macOS): npx @tauri-apps/cli dev — mining page works, hashrate displays, proofs submit
  • iOS: APPLE_DEVELOPMENT_TEAM=<ID> npx @tauri-apps/cli ios build — install on iPhone, connect wallet, start mining
  • Android: npx @tauri-apps/cli android build --apk --target aarch64 — sign APK, install, test mining
  • Browser: yarn start — WASM mining fallback works without Tauri
  • Verify mining continues during proof submission (no hashrate drop)
  • Verify safe areas on iPhone (notch, home indicator)
  • Verify wallet connect flow on mobile (Keys → add key → wallet → mnemonic)

🤖 Generated with Claude Code

Andrejs and others added 30 commits May 13, 2024 11:39
- chore(tauri-app): use IS_TAURI env var instead of window.__TAURI__
- fix(cyb): request persistens storage permission error handling
Michael Borisov and others added 10 commits February 27, 2026 20:14
…ring mining

The react-force-graph-3d library's D3-timer module creates setInterval(poke, 1000)
on every animation frame. WebKit accumulates these instead of replacing them,
causing 85% CPU usage on every page (graph is in the global footer).

Fix: intercept setInterval in CyberlinksGraph, track all IDs created by the
ForceGraph3D internals, and aggressively sweep them every 100ms. This keeps
the built-in animation loop running (correct visuals) while preventing the
timer cascade.

Also: unmount the 3D graph entirely during active mining via Redux state
(mining.active), dropping WebKit from 85% to 6-9% during mining.

Other changes in this commit:
- Tauri: RunEvent::Exit handler for IPFS/mining cleanup
- Mining: stabilize polling with processQueueRef pattern
- Mining: replace react-query refetchInterval with manual 30s timer
- Mining: add emission simulator, staking/referral sections
- Mining hooks: fetchRef pattern to avoid interval churn

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…endering bug

The global CSS rules `input:focus::-webkit-input-placeholder { opacity: 0 }`
triggered a WebKit compositing bug in Tauri where the entire input element
stopped painting when focused and empty. Also changed global placeholder
color from teal (#3ab793) to gray (#777). Added focus box-shadow and
min-height to mining staking inputs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Mining process persists across page navigation (Tauri backend keeps
  running, WASM miner moved to module scope)
- New useMiningMonitor hook in App.tsx polls backend every 1s, stores
  full MiningStatus in Redux as single source of truth
- MiningBadge in header always shows correct hashrate via Redux
- Mining page reads status from Redux instead of local state
- Click-through guard prevents stale ActionBar clicks from stopping mining
- Replace SimulatorSection with live ConfigPanel (admin config management)
- Add StakingSection with CW20 balance, APR formatting (T/B/M/K tiers)
- Add ReferralSection, ConfigPanel, WebSocket block subscription
- Generated lithium contract TypeScript clients
- Tauri: GPU backend selection, metrics tracking, proof relay support
- Fix splashscreen overlap (both windows start hidden)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bufferTime(0) in RxBroadcastChannelListener caused RxJS AsyncScheduler
to create/clear ~144K setInterval(fn, 0) calls per second, consuming
85% CPU in WebKit. Changed to bufferTime(200) for reasonable batching.

Also removed the useIntervalSweep hack from CyberlinksGraph that was
a workaround for this bug (incorrectly attributed to d3-timer).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Regenerate all platform icons (macOS, iOS, Android, Windows)
- Swap portal menu: small icon uses glow SVG, large uses original
- Update favicon
- Menu component styling improvements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t Logs button

Relay was broken: contract requires sender==miner but relay signed as
activator. Changed to account activation flow — relay sends 1boot to
create new accounts, then cyb-ts retries proof submission directly.

Added Export Logs button on Mining page for testers to copy full session
diagnostics (config, hashrate, proof log, network stats) to clipboard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- cyb-boot Rust binary: decrypts boot.dat, writes bootstrap.json, downloads .pkg
- Distribution server integration: web encrypts wallet, server returns zip with signed binary + boot.dat
- DownloadSection component: platform detection, AES-256-GCM encryption, download trigger
- Tauri bootstrap import: read_bootstrap command imports wallet on first launch
- macOS release CI: GitHub Actions workflow with code signing + notarization
- Artifacts: .dmg, .pkg, cyb-boot published to GitHub Releases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment on lines +21 to +209
runs-on: macos-14 # Apple Silicon (M1)
timeout-minutes: 120

steps:
- name: Checkout
uses: actions/checkout@v4

# ── Toolchain ───────────────────────────────────────────────
- name: Setup Deno
uses: denoland/setup-deno@v2
with:
deno-version: ${{ env.DENO_VERSION }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin

- name: Rust cache
uses: Swatinem/rust-cache@v2
with:
workspaces: |
src-tauri -> target
cyb-boot -> target

# ── Apple Code Signing ──────────────────────────────────────
- name: Import Apple certificates
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_INSTALLER_CERTIFICATE: ${{ secrets.APPLE_INSTALLER_CERTIFICATE }}
APPLE_INSTALLER_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_INSTALLER_CERTIFICATE_PASSWORD }}
run: |
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)

security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"

# Import Developer ID Application certificate
echo "$APPLE_CERTIFICATE" | base64 --decode > $RUNNER_TEMP/app-cert.p12
security import $RUNNER_TEMP/app-cert.p12 \
-P "$APPLE_CERTIFICATE_PASSWORD" \
-A -t cert -f pkcs12 \
-k "$KEYCHAIN_PATH"
rm -f $RUNNER_TEMP/app-cert.p12

# Import Developer ID Installer certificate (for .pkg signing)
echo "$APPLE_INSTALLER_CERTIFICATE" | base64 --decode > $RUNNER_TEMP/pkg-cert.p12
security import $RUNNER_TEMP/pkg-cert.p12 \
-P "$APPLE_INSTALLER_CERTIFICATE_PASSWORD" \
-A -t cert -f pkcs12 \
-k "$KEYCHAIN_PATH"
rm -f $RUNNER_TEMP/pkg-cert.p12

# Make keychain available for codesign
security list-keychains -d user -s "$KEYCHAIN_PATH" login.keychain-db
security default-keychain -s "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple:,codesign:,productbuild: \
-s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"

# Auto-detect signing identities from imported certs
APP_IDENTITY=$(security find-identity -v -p codesigning "$KEYCHAIN_PATH" \
| grep 'Developer ID Application' | head -1 | sed 's/.*"\(.*\)"/\1/')
PKG_IDENTITY=$(security find-identity -v -p basic "$KEYCHAIN_PATH" \
| grep 'Developer ID Installer' | head -1 | sed 's/.*"\(.*\)"/\1/')

# Fall back to secrets if auto-detection fails
APP_IDENTITY="${APP_IDENTITY:-${{ secrets.APPLE_SIGNING_IDENTITY }}}"
PKG_IDENTITY="${PKG_IDENTITY:-${{ secrets.PKG_SIGNING_IDENTITY }}}"

echo "APPLE_SIGNING_IDENTITY=$APP_IDENTITY" >> $GITHUB_ENV
echo "PKG_SIGNING_IDENTITY=$PKG_IDENTITY" >> $GITHUB_ENV
echo "KEYCHAIN_PATH=$KEYCHAIN_PATH" >> $GITHUB_ENV

echo "App signing identity: $APP_IDENTITY"
echo "Pkg signing identity: $PKG_IDENTITY"

- name: Setup Apple API key
env:
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
run: |
mkdir -p $RUNNER_TEMP/private_keys
echo "$APPLE_API_KEY_BASE64" | base64 --decode \
> $RUNNER_TEMP/private_keys/AuthKey_${APPLE_API_KEY}.p8

echo "APPLE_API_KEY=$APPLE_API_KEY" >> $GITHUB_ENV
echo "APPLE_API_ISSUER=${{ secrets.APPLE_API_ISSUER }}" >> $GITHUB_ENV
echo "APPLE_API_KEY_PATH=$RUNNER_TEMP/private_keys/AuthKey_${APPLE_API_KEY}.p8" >> $GITHUB_ENV

# ── Dependencies ────────────────────────────────────────────
- name: Install JS dependencies
run: deno install

- name: Download Kubo sidecar
run: |
TAURI_TARGET_TRIPLE=aarch64-apple-darwin \
src-tauri/scripts/download-kubo.sh ${{ env.KUBO_VERSION }}

# ── Build ───────────────────────────────────────────────────
- name: Build web frontend
run: deno task build-tauri
env:
NODE_OPTIONS: '--max-old-space-size=8192'

- name: Build Tauri app (sign + notarize)
run: |
npx @tauri-apps/cli build \
--target aarch64-apple-darwin \
--config '{"build":{"beforeBuildCommand":""},"bundle":{"macOS":{"signingIdentity":"'"$APPLE_SIGNING_IDENTITY"'"}}}' \
-- --features gpu-metal

- name: Build .pkg (sign + notarize)
run: |
src-tauri/scripts/macos-pkg.sh \
--app-path src-tauri/target/aarch64-apple-darwin/release/bundle/macos/cyb.app \
--output-dir src-tauri/target/aarch64-apple-darwin/release/bundle/pkg

- name: Build cyb-boot (sign + notarize)
run: |
cd cyb-boot && cargo build --release --target aarch64-apple-darwin
cd ..

codesign --force --options runtime --sign "$APPLE_SIGNING_IDENTITY" \
cyb-boot/target/aarch64-apple-darwin/release/cyb-boot

ditto -c -k --keepParent \
cyb-boot/target/aarch64-apple-darwin/release/cyb-boot \
$RUNNER_TEMP/cyb-boot-notarize.zip

xcrun notarytool submit $RUNNER_TEMP/cyb-boot-notarize.zip \
--key "$APPLE_API_KEY_PATH" \
--key-id "$APPLE_API_KEY" \
--issuer "$APPLE_API_ISSUER" \
--wait

rm -f $RUNNER_TEMP/cyb-boot-notarize.zip

# ── Artifacts ───────────────────────────────────────────────
- name: Collect release artifacts
run: |
mkdir -p release-artifacts

# .dmg
cp src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/*.dmg \
release-artifacts/

# .pkg (for GitHub Releases — cyb-boot downloads this)
cp src-tauri/target/aarch64-apple-darwin/release/bundle/pkg/*.pkg \
release-artifacts/cyb.pkg

# cyb-boot binary (for distribution server)
cp cyb-boot/target/aarch64-apple-darwin/release/cyb-boot \
release-artifacts/cyb-boot-aarch64-apple-darwin

echo "=== Release artifacts ==="
ls -lh release-artifacts/

- name: Create GitHub Release
if: startsWith(github.ref, 'refs/tags/') || inputs.create_release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name || format('v{0}', github.sha) }}
files: release-artifacts/*
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload build artifacts
if: ${{ !startsWith(github.ref, 'refs/tags/') && !inputs.create_release }}
uses: actions/upload-artifact@v4
with:
name: macos-release-aarch64
path: release-artifacts/

# ── Cleanup ─────────────────────────────────────────────────
- name: Cleanup keychain
if: always()
run: |
if [ -n "${KEYCHAIN_PATH:-}" ]; then
security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true
fi

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 2 days ago

In general, the problem is fixed by adding an explicit permissions block that grants only the scopes required by the workflow. This can be added at the root of the workflow (applies to all jobs) or at the job level. Here, the only steps that need write access to the repository via GITHUB_TOKEN are:

  • Create GitHub Release using softprops/action-gh-release@v2 (needs contents: write to create/update releases on tags/commits).
  • actions/upload-artifact@v4 uses the workflow’s GITHUB_TOKEN internally but works with contents: read; it doesn’t need repo write permissions.

The best minimal fix without changing behavior is therefore:

  • Add a workflow-level permissions block setting contents: read as the default for all jobs/steps.
  • Add a job-level permissions block for macos-release overriding contents to write, since the job creates GitHub Releases. This keeps permissions narrow while still allowing the existing Create GitHub Release step to function.

We will modify .github/workflows/macos_release.yml as follows:

  • After line 15 (after the on: block), insert a root-level permissions: block with contents: read.
  • After line 22 (inside jobs:, under macos-release: and at the same indentation as runs-on), insert a job-level permissions: block with contents: write.

No imports or additional methods are needed; GitHub Actions understands permissions natively.

Suggested changeset 1
.github/workflows/macos_release.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/macos_release.yml b/.github/workflows/macos_release.yml
--- a/.github/workflows/macos_release.yml
+++ b/.github/workflows/macos_release.yml
@@ -13,6 +13,9 @@
     tags:
       - 'v*'
 
+permissions:
+  contents: read
+
 env:
   DENO_VERSION: v2.x
   NODE_VERSION: '22'
@@ -20,6 +23,8 @@
 
 jobs:
   macos-release:
+    permissions:
+      contents: write
     runs-on: macos-14  # Apple Silicon (M1)
     timeout-minutes: 120
 
EOF
@@ -13,6 +13,9 @@
tags:
- 'v*'

permissions:
contents: read

env:
DENO_VERSION: v2.x
NODE_VERSION: '22'
@@ -20,6 +23,8 @@

jobs:
macos-release:
permissions:
contents: write
runs-on: macos-14 # Apple Silicon (M1)
timeout-minutes: 120

Copilot is powered by AI and may make mistakes. Always verify output.
Michael Borisov and others added 7 commits March 6, 2026 21:45
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add tauri-plugin-deep-link for iOS/Android Universal Links (cyb.ai URLs
  open in app, preserving ?ref= referrer)
- Handle deep link URLs at app init via getCurrent() + onOpenUrl()
- Fix cyb-boot PKG download URL to use cyberia-to/cyb repo
- Enrich mining log export with device info, Tauri backend metrics,
  uhash params, block context, proof summary stats
- Switch log export from clipboard to file download

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace SCP deploy to Jupiter with HMAC-authenticated webhook trigger
- Server now runs locally on Cyberproxy (no Jupiter proxy hop)
- Rename Install-cyb.zip → boot-cyb.zip, Install cyb.app → boot cyb.app
- API path: POST /api/boot (was /api/boot/boot)
- Server handler: / (was /boot)
- Add boot server Go source and docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Michael Borisov and others added 11 commits March 7, 2026 19:52
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t.dat discovery

- Rename boot-cyb.zip → boot_cyb.zip and boot cyb.app → Boot Cyb.app everywhere
- Add ~/Desktop as boot.dat search path
- Scan immediate subdirectories of ~/Downloads and ~/Desktop for boot.dat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Check bootstrap.json before localStorage so that wallet imported
via cyb-boot takes priority over any previously generated wallet.
The file is deleted after reading, so this only applies once.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Headline: "Mine 10x faster in app"
- Desktop: platform-detected download button
- Mobile: "coming soon" button for iOS/Android

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add tauri-plugin-dialog and tauri-plugin-fs for native file operations.
Export logs now opens a Save dialog on desktop instead of copying to clipboard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hashrate was jumping wildly due to bursty counter + double smoothing:
- Backend 5s rolling window was shorter than batch time (~7s)
- Frontend EMA re-derived rate from total_hashes delta, seeing mostly
  zeros between batches then a spike when a batch completed

Fixes:
- Backend: increase rolling window from 5s to 30s (fits multiple batches)
- Backend: record snapshots on proof-found path (was missing)
- Frontend: remove EMA re-derivation, use backend's rolling hashrate directly
- Add session average display below main hashrate as stable anchor
- Downsample sparkline to 5s intervals instead of every render

Also adds:
- Proof retry queue with exponential backoff for transport errors
- RPC connection health tracking with offline indicator
- Sleep/wake and network reconnection recovery
- Native save dialog capability for log export

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…port

Replace timer polling (10s/120s) with event-driven refresh:
- New block (WS) triggers refetchAll for all display data
- resyncAfterProof fetches config + balance after proof submit
- 30s fallback interval only when WebSocket is disconnected
- Wake/resume/online handlers use refetchAll + refetchConfig

Local sequence tracking eliminates account sequence mismatch errors:
- Track accountNumber + sequence in seqRef, increment on success
- Use sign() + broadcastTx() instead of execute() to pass explicit SignerData
- On sequence mismatch: re-fetch from chain and retry once
- Reset sequence on unknown errors or account activation

Fix cooldown bypass after failed submissions:
- Set lastSubmitTimeRef before await (was only set on success)
- Prevents rapid-fire cascade of failures at 1s intervals

Other:
- Export logs filtered to current app session only
- Tx details page polls until confirmed
- Embed challenge in Rust FoundProof for stale-proof tracking
- Refresh badge shows 'reconnecting...' instead of countdown

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removing setSessionLiMined(0) from handleStartMining prevents the
"LI Mined" counter from resetting when changing difficulty or
restarting mining mid-session.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…conomy section

- Remove emission rate cards (mining/staking/gross) — these are internal
  PID controller values (atomic LI/s), not actual token emission rates
- Add Economy section: supply (minted/cap), PoW/PoS share, fees, burned
- Add total_minted query from core contract
- Replace Alpha/Beta with PoW/PoS share (computed from emission ratios)
- Replace D-rate with Net. throughput (bits/hr)
- Add Your share (miner's network share %)
- Add window progress bar with fill indicator
- Fix horizontal scroll (overflow-x: hidden, min-width: 0)
- Add P (peta) tier to compactLi for supply cap display
- StatCard: add children prop for progress bar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants